package com.xcity.game.buildv2;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xcity.db.entity.Employee;
import com.xcity.db.entity.Player;
import com.xcity.game.assist.AssistBuild;
import com.xcity.game.battle.pve.PVEStage;
import com.xcity.game.battle.pve.template.StageTemplate;
import com.xcity.game.buildv2.BuildV2.State;
import com.xcity.game.buildv2.template.BuildTemplateV2;
import com.xcity.game.combat.listener.combat.PVPCombatListenerV2;
import com.xcity.game.common.Cause;
import com.xcity.game.common.Currency;
import com.xcity.game.common.MessageConst;
import com.xcity.game.event.GameEvents;
import com.xcity.game.item.GameItem;
import com.xcity.game.item.ItemEffect;
import com.xcity.game.item.ItemTemplate;
import com.xcity.game.player.cache.PlayerCacheService;
import com.xcity.game.player.robot.RobotUtils;
import com.xcity.pomelo.PomeloRoute;
import com.xcity.pomelo.push.SyncPush;
import com.xcity.pomelo.push.sync.MapSync;
import com.xcity.pomelo.request.BuildCreateV2Request;
import com.xcity.pomelo.request.BuildListV2Request;
import com.xcity.pomelo.request.BuildPartLevelUpV2Request;
import com.xcity.pomelo.request.BuildPutExpBookRequest;
import com.xcity.pomelo.request.BuildTakeExpRequest;
import com.xcity.pomelo.request.BuildV2Request;
import com.xcity.pomelo.request.DefendOtherBuildRequest;
import com.xcity.pomelo.request.EmployeeFreeAllRequest;
import com.xcity.pomelo.request.EmployeeFreeRequest;
import com.xcity.pomelo.request.EmployeeWorkRequest;
import com.xcity.pomelo.request.TakeBuildAllMoneyRequest;
import com.xcity.pomelo.request.TakeBuildMoneyV2Request;
import com.xcity.pomelo.response.BuildCreateV2Response;
import com.xcity.pomelo.response.BuildListV2Response;
import com.xcity.pomelo.response.BuildPutExpBookResponse;
import com.xcity.pomelo.response.BuildTakeExpResponse;
import com.xcity.pomelo.response.BuildTakeExpResponse.ExpDelta;
import com.xcity.pomelo.response.BuildV2PartLevelUpResponse;
import com.xcity.pomelo.response.BuildV2Response;
import com.xcity.pomelo.response.DefendOtherBuildResponse;
import com.xcity.pomelo.response.EmployeeFreeAllResponse;
import com.xcity.pomelo.response.EmployeeFreeResponse;
import com.xcity.pomelo.response.EmployeeWorkResponse;
import com.xcity.pomelo.response.HintResponse;
import com.xcity.pomelo.response.TakeBuildAllMoneyResponse;
import com.xcity.pomelo.response.TakeBuildMoneyV2Response;

import gnu.trove.map.TIntObjectMap;
import gnu.trove.map.hash.TIntObjectHashMap;
import naga.x.App;
import naga.x.event.Event;
import naga.x.event.EventListener;
import naga.x.game.template.TemplateService;
import naga.x.game.time.TimeUpdater;
import naga.x.net.Session;
import naga.x.net.annotation.OPHandler;
import naga.x.net.impl.pomelo.annotation.PomeloOP;
import naga.x.service.Service;
import naga.x.service.ServiceException;

@OPHandler
public class BuildServiceV2 implements Service, EventListener {

	protected List<BuildTemplateV2> templates;
	protected TIntObjectMap<BuildTemplateV2> templatesMap;
	protected TIntObjectMap<BuildTemplateV2> stage2buildingMap; // key:关卡id, value:解锁建筑
	
	protected static final Logger LOG = LoggerFactory.getLogger(BuildServiceV2.class);
	
	@Override
	public void startup() throws ServiceException {
		templates = App.getApp().getServiceManager().get(TemplateService.class).getTemplatesList(BuildTemplateV2.class);
		templatesMap = App.getApp().getServiceManager().get(TemplateService.class).getTemplates(BuildTemplateV2.class);
		int size = templates.size();
		stage2buildingMap = new TIntObjectHashMap<BuildTemplateV2>(size >> 1); // size * Constants.DEFAULT_LOAD_FACTOR
		for (int i = 0; i < size; i++) {
			BuildTemplateV2 template = templates.get(i);
			StageTemplate stageTemplate = template.getUnlockStage();
			if (stageTemplate != null) {
				stage2buildingMap.put(stageTemplate.getId(), template);
			}
		}
		App.getApp().getEventManager().register(this);
	}

	@Override
	public void shutdown() throws ServiceException {
	}

	@Override
	public String getId() {
		return getClass().getName();
	}
	
	@Override
	public int[] getEventTypes() {
		return new int[] { GameEvents.EVENT_PVE_SUCCESS };
	}

	@Override
	public void handleEvent(Event event) {
		firePvePassed(event);
	}
	
	private void firePvePassed(Event event) {
		boolean isFirstPass = event.getParameter(4);
		if (isFirstPass) {
			Player player = event.getParameter(0);
			PVEStage stage = event.getParameter(1);
			BuildTemplateV2 template = stage2buildingMap.get(stage.getId());
			if (template == null) {
				return;
			}
			BuildV2 building = player.getBuildings2().find(template.getId());
			if (building == null) {
				player.send(new MapSync(SyncPush.SYNC_BUILD_STATE, template.getId(), State.UNLOCKED));
				return;
			}
			if (building.getState() != State.LOCKED) {
				return;
			}
			building.setState(State.CAN_BUILD);
			player.send(new MapSync(SyncPush.SYNC_BUILD_STATE, building.getId(), building.getState()));
			LOG.info("[BUILD UNLOCKED]ID[{}]BUILD[{}]STAGE[{}]CAUSE[{}]", player.getId(), stage.getId(), Cause.PVE_END);
		}
	}

	public BuildTemplateV2 getTemplate(int pos) {
		return pos >= 0 && pos < templates.size() ? templates.get(pos) : null;
	}
	
	public BuildTemplateV2 findTemplate(int id) {
//		for (int i = 0, size = templates.size(); i < size; i++) {
//			BuildTemplateV2 template = templates.get(i);
//			if (id == template.getId()) {
//				return template;
//			}
//		}
//		return null;
		return templatesMap.get(id);
	}
	
	@PomeloOP(PomeloRoute.BUILD_LIST_V2)
	protected void requestList(Session session, BuildListV2Request req) {
		Player player = session.getClient();
		session.send(new BuildListV2Response(req.getSerial(), player, templates));
	}
	
	@PomeloOP(PomeloRoute.BUILD_INFO_V2)
	protected void requestInfo(Session session, BuildV2Request req) {
		Player player = session.getClient();
		BuildV2 building = player.getBuildings2().find(req.getId());
		if (building != null) {
			session.send(new BuildV2Response(req.getSerial(), player, building));
			return;
		}
		BuildTemplateV2 template = findTemplate(req.getId());
		if (template != null) {
			session.send(new BuildV2Response(req.getSerial(), player, template));
			return;
		}
		session.send(new HintResponse(req.getSerial(), MessageConst.BUILDING_NOT_EXIST));
	}
	
	@PomeloOP(PomeloRoute.BUILD_CREATE_V2)
	protected void requestCreate(Session session, BuildCreateV2Request req) {
		if (req.getId() <= 0) {
			session.send(new HintResponse(req.getSerial(), MessageConst.ILLEGAL_OPERATION));
			return;
		}
		Player player = session.getClient();
		BuildV2 building = player.getBuildings2().find(req.getId());
		if (building == null) {
			BuildTemplateV2 template = findTemplate(req.getId());
			StageTemplate stageTemplate = template != null ? template.getUnlockStage() : null;
			String msg = stageTemplate != null ? MessageFormat.format(MessageConst.BUILDING_UNLOCK_WHEN_PVE_PASS, stageTemplate.getName()) : MessageConst.BUILDING_NOT_EXIST;
			session.send(new HintResponse(req.getSerial(), msg));
			return;
		}
		if (building.getState() != State.CAN_BUILD) {
			StageTemplate stageTemplate = building.getState() == State.LOCKED ? building.getTemplate().getUnlockStage() : null;
			String msg = stageTemplate != null ? MessageFormat.format(MessageConst.BUILDING_UNLOCK_WHEN_PVE_PASS, stageTemplate.getName()) : MessageConst.BUILDING_CAN_NOT_BE_BUILD_V2;
			session.send(new HintResponse(req.getSerial(), msg));
			return;
		}
		building.setState(State.BUILDING);
		session.send(new BuildCreateV2Response(req.getSerial(), building));
		App.getApp().getEventManager().addEvent(GameEvents.EVENT_START_BUILDING_V2, player, building);
		LOG.info("[BUILD V2 CREATE]ID[{}]BUILD[{}]CAUSE[{}]", player.getId(), building.getId(), Cause.MANUAL);
	}
	
	@PomeloOP(PomeloRoute.BUILD_PART_LEVEL_UP_V2)
	protected void requestPartLevelUp(Session session, BuildPartLevelUpV2Request req) {
		if (req.getId() <= 0 || req.getPart() < 0 || req.getPart() >= BuildV2.PART_COUNT) {
			session.send(new HintResponse(req.getSerial(), MessageConst.ILLEGAL_OPERATION));
			return;
		}
		Player player = session.getClient();
		BuildV2 building = player.getBuildings2().find(req.getId());
		if (building == null) {
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILDING_NOT_EXIST));
			return;
		}
		if (building.getState() == State.BUILT) {
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILDING_FINISH_V2));
			return;
		}
		if (building.getState() == State.CAPTURED) {
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_OCCUPIED_BY_OTHER));
			return;
		}
		if (building.getState() != State.BUILDING) {
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILDING_CAN_NOT_BE_BUILD_V2));
			return;
		}
		BuildV2Part part = building.getPart(req.getPart());
		if (part == null) {
			session.send(new HintResponse(req.getSerial(), MessageConst.ILLEGAL_OPERATION));
			return;
		}
		if (part.level >= BuildV2Part.MAX_LEVEL) {
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILDING_PART_FINISHED));
			return;
		}
		int gold = part.template.getGold(part.level + 1);
		if (!player.isEnough(Currency.GOLD, gold)) {
			session.send(new HintResponse(req.getSerial(), MessageConst.GOLD_NOT_ENOUGH));
			return;
		}
		ItemTemplate item = part.template.getItem();
		int itemCount = part.template.getItemCount(part.level + 1);
		if (!player.getBag().removeItem(item.getId(), itemCount, Cause.BUILD_LEVEL_UP)) {
			session.send(new HintResponse(req.getSerial(), MessageFormat.format(MessageConst.ITEM_NOT_ENOUGH, item.getName())));
			return;
		}
		player.costGold(gold, Cause.BUILD_LEVEL_UP);
		building.levelUp(req.getPart(), Cause.MANUAL);
		session.send(new BuildV2PartLevelUpResponse(req.getSerial(), player, building, part));
	}
	
	@PomeloOP(PomeloRoute.EMPLOYEE_WORK)
	protected void requestEmployeeInBuild(Session session, EmployeeWorkRequest req) {
		Player player = session.getClient();
		BuildV2 build = player.getBuildings2().find(req.getBuildId());
		if (build == null) {
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILDING_NOT_EXIST));
			return;
		}
		State bstate = build.getState();
		if (bstate == State.CAPTURED) {
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_ADD_EMPLOYEE_WHEN_CAPTURED));
			return;
		}
		if (bstate != State.BUILT) {
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_ADD_EMPLOYEE_WHEN_NOT_BUILDING_OK));
			return;
		}
		Employee employee = player.getEmployees().get(req.getId());
		if (employee == null) {
			session.send(new HintResponse(req.getSerial(), MessageConst.EMPLOYEE_NOT_EXIST));
			return;
		}
		com.xcity.db.entity.Employee.State state = com.xcity.db.entity.Employee.State.FREE;
		if (state.enable && employee.getState() != state) {
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_CAPTURE_ONLY_USE_STATE_FREE_EMPLOYEE));
			return;
		}
		if (req.getPos() < 0 || req.getPos() >= BuildV2.MAX_SLOT) {
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_SLOT_LOCKED));
			return;
		}
		int cd = player.getBuildings2().checkInCD();
		if (cd > 0) {
			session.send(new HintResponse(req.getSerial(), MessageFormat.format(MessageConst.BUILD_ADD_EMPLOYEE_IN_CD, cd)));
			return;
		}
		build.addEmployee(employee, req.getPos());
		App.getApp().getEventManager().addEvent(GameEvents.EVENT_EMPLOYEE_PUT_IN_BUILD, player, build, employee);
		session.send(new EmployeeWorkResponse(req.getSerial(), build, employee, req.getPos()));
		LOG.info("[EMPLOYEE STATE DEFENSE]ID[{}]BUILD[{}]EMPLOYEE[{}]EID[{}]STATE[{}]", player.getId(), build.getId(), employee.getTemplate().getId(), employee.getId(), employee.getState());
	}
	
	@PomeloOP(PomeloRoute.EMPLOYEE_FREE)
	protected void requestOffWork(Session session, EmployeeFreeRequest req) {
		Player player = session.getClient();
//		Build build = player.getBuildings().getBuild(req.getBuildId());
		BuildV2 build = player.getBuildings2().find(req.getBuildId());
		if (build == null) {
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILDING_NOT_EXIST));
			return;
		}
		Employee employee = player.getEmployees().get(req.getId());
		if (employee == null) {
			session.send(new HintResponse(req.getSerial(), MessageConst.EMPLOYEE_NOT_EXIST));
			return;
		}
		Employee.State state = Employee.State.DEFENSE;
		if (state.enable && employee.getState() != state) {
			session.send(new HintResponse(req.getSerial(), MessageConst.EMPLOYEE_NOT_IN_BUILD));
			return;
		}
		ExpDelta expdelta = new ExpDelta(0, 0, 0);
		int pos = build.removeEmployee(employee, expdelta);
		session.send(new EmployeeFreeResponse(req.getSerial(), build, employee.getId(), pos, expdelta));
		LOG.info("[EMPLOYEE STATE FREE]ID[{}]BUILD[{}]EMPLOYEE[{}]EID[{}]STATE[{}]", player.getId(), build.getId(), employee.getTemplate().getId(), employee.getId(), employee.getState());
		player.getBuildings2().resetLastRemoveEmployeeTime();
	}

	@PomeloOP(PomeloRoute.EMPLOYEE_FREE_ALL)
	protected void requestOffWorkAll(Session session, EmployeeFreeAllRequest req){
		Player player = session.getClient();
		BuildV2 build = player.getBuildings2().find(req.getBuildId());
		if(build == null){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILDING_NOT_EXIST));
			return;
		}
		ExpDelta expdelta = new ExpDelta(0, 0, 0);
		int ret = build.removeAllEmployee(expdelta);
		player.send(new EmployeeFreeAllResponse(req.getSerial(), build, ret, expdelta));
		LOG.info("[EMPLOYEE FREE ALL]ID[{}]BUILD[{}]COUNT[{}]", player.getId(), build.getId(), ret);
		player.getBuildings2().resetLastRemoveEmployeeTime();
	}
	
	
	@PomeloOP(PomeloRoute.DEFEND_OTHER_BUILD)
	protected void requestCapture(Session session, DefendOtherBuildRequest req) {
		Player player = session.getClient();
		long destId = req.getPid();
		int destBuildId = req.getBid();
		if (destId == 0 || destId == player.getId() || destBuildId == 0) {
			session.send(new HintResponse(req.getSerial(), MessageConst.ILLEGAL_OPERATION));
			return;
		}
		if (destId == player.getId()) {
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_OCCUPY_SELF));
			return;
		}
		Player target = App.getApp().getServiceManager().get(PlayerCacheService.class).find(destId);
		if (target == null) {
			session.send(new HintResponse(req.getSerial(), MessageConst.PLAYER_NOT_EXIST));
			return;
		}
		if (RobotUtils.isRobot(target)) { // 不能占领机器人建筑
			session.send(new DefendOtherBuildResponse(req.getSerial()));
			return;
		}
		BuildV2 build = target.getBuildings2().find(destBuildId);
		if (build == null) {
			session.send(new HintResponse(req.getSerial(), MessageConst.TARGET_PLAYER_BUILD_NOT_EXIST));
			return;
		}
//		build.update(); // force update
		if (build.getInvaderId() != player.getId()) {
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_NOT_OCCUPY));
			return;
		}
		long[] eids = req.getEids() != null && req.getEids().length > 0 ? req.getEids() : null;
		if (eids != null && build.wasCapturedOperateTimeout()) {
			session.send(new HintResponse(req.getSerial(), MessageConst.OP_TIME_OUT));
			return;
		}
		byte type = (byte) (eids != null ? 1 : 0);
		if (eids != null) { // 占领
			if(eids.length != BuildV2.MAX_SLOT){
				session.send(new HintResponse(req.getSerial(), MessageFormat.format(MessageConst.BUILD_CAPTURE_EMPLOYEES_MUST_COUNT, BuildV2.MAX_SLOT)));
				return;
			}
			if (eids.length > BuildV2.MAX_SLOT) {
				session.send(new HintResponse(req.getSerial(), MessageFormat.format(MessageConst.BUILD_CAPTURE_EMPLOYEES_TOO_MUCH, BuildV2.MAX_SLOT)));
				return;
			}
			List<Employee> filtered = new ArrayList<Employee>(eids.length);
			StringBuilder LOGBUF = new StringBuilder();
			for (long eid : eids) {
				Employee e = player.getEmployees().get(eid);
				if (e != null) {
					Employee.State state = Employee.State.FREE;
					if (state.enable && e.getState() != state) {
						session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_CAPTURE_ONLY_USE_STATE_FREE_EMPLOYEE));
						return;
					}
					filtered.add(e);
					if (LOGBUF.length() > 0) {
						LOGBUF.append(", ");
					}
					LOGBUF.append(e.getId());
				}
			}
			eids = build.capture(player, filtered, Cause.MANUAL);
			PVPCombatListenerV2.doCaptureCallback(player, true);
//			LOG.info("[BUILD CAPTURED]ID[{}]DEST[{}]BUILD[{}]EMPLOYEES[{}]", player.getId(), target.getId(), build.getId(), LOGBUF);
		} else { // 放弃占领
			eids = build.unCapture(player, Cause.MANUAL, true);
			PVPCombatListenerV2.doCaptureCallback(player, false);
//			LOG.info("[BUILD UNCAPTURED]ID[{}]DEST[{}]BUILD[{}]", player.getId(), target.getId(), build.getId());
		}
//		if (target instanceof Actor) {
//			((Actor) target).setDirty(true);
//		}
		
		session.send(new DefendOtherBuildResponse(req.getSerial(), build, type));
	}
	
	
	@PomeloOP(PomeloRoute.TAKE_BUILD_MONEY_V2)
	protected void requestTakeMoney(Session session, TakeBuildMoneyV2Request req){
		Player player = session.getClient();
		BuildV2 build = player.getBuildings2().find(req.getBuildId());
		if(build == null){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILDING_NOT_EXIST));
			return;
		}
		if(build.getState() == State.BUILDING){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILDING_NOW));
			return;
		}
		if(build.getState() == State.CAPTURED){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_OCCUPIED_BY_OTHER));
			return;
		}
		if(build.getState() == State.ASSISTED){
			//协助建筑的话计算协助人的员工和时间
			Player assistant = App.getApp().getServiceManager().get(PlayerCacheService.class).find(build.getAssistId());
			if(assistant == null){
				player.send(new HintResponse(req.getSerial(), MessageConst.ASSIST_NO_ASSIST_BUILD));
				return;
			}
			long now = TimeUpdater.getInstance().now();
			AssistBuild assbuild = assistant.getAssists().findByOwnerId(player.getId());
			int takeMoney = 0;
			if(assbuild != null){
				int[] takes = assbuild.takeMoney(assistant, now, build, false);
				takeMoney = takes[0];
			}
			player.send(new TakeBuildMoneyV2Response(req.getSerial(), build, assbuild, takeMoney, now));
			return;
		}
		if(build.getState() != State.BUILT){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILDING_NOT_EXIST));
			return;
		}
		String error = build.takeMoney(true, false);
		if(error != null){
			session.send(new HintResponse(req.getSerial(), error));
			return;
		}
		session.send(new TakeBuildMoneyV2Response(req.getSerial(), build, null, 0, 0));
	}
	
	@PomeloOP(PomeloRoute.TAKE_BUILD_ALLMONEY)
	protected void requestTakeAllMoney(Session session, TakeBuildAllMoneyRequest req){
		Player player = session.getClient();
		int total = player.getBuildings2().tryTakeAllMoney();
		
		player.send(new TakeBuildAllMoneyResponse(req.getSerial(), total));
	}
	

//	@PomeloOP(PomeloRoute.BUILD_PUT_EXP_BOOK)
	@Deprecated //暂时屏蔽
	protected void requestPutExpBook(Session session, BuildPutExpBookRequest req){
		Player player = session.getClient();
		BuildV2 build = player.getBuildings2().find(req.getBuildId());
		if(build == null){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILDING_NOT_EXIST));
			return;
		}
		if(build.getState() == State.BUILDING){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILDING_NOW));
			return;
		}
		if(build.getState() == State.CAPTURED){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_OCCUPIED_BY_OTHER));
			return;
		}
		int state = build.checkExpBookState();
		if(state == BuildV2.BOOK_STATE_CANNOT_PUT){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_ALREADY_PUT_EXP_BOOK));
			return;
		}
		if(!build.hasEmployee()){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_HAS_NO_EMPLOYEE));
			return;
		}
		GameItem item = player.getBag().getItem(req.getItemInstId());
		if(item == null){
			session.send(new HintResponse(req.getSerial(), MessageConst.ITEM_NOT_EXIST));
			return;
		}
		ItemTemplate itemTemplate = item.getTemplate();
		if(itemTemplate.getEffect() != ItemEffect.ADD_EMPLOYEE_EXP){
			session.send(new HintResponse(req.getSerial(), MessageConst.ITEM_CANNOT_USE));
			return;
		}
		item = player.getBag().removeItem(req.getItemInstId(), 1, Cause.BUILD_PUT_EXP_BOOK);
		if(item == null){
			session.send(new HintResponse(req.getSerial(), MessageFormat.format(MessageConst.ITEM_NOT_ENOUGH, itemTemplate.getName())));
			return;
		}
		build.realPutExpBook(itemTemplate);
		session.send(new BuildPutExpBookResponse(req.getSerial(), player, build));
	}
	
//	@PomeloOP(PomeloRoute.BUILD_TAKE_EXP)
	@Deprecated //暂时屏蔽
	protected void requestTakeExp(Session session, BuildTakeExpRequest req){
		Player player = session.getClient();
		BuildV2 build = player.getBuildings2().find(req.getBuildId());
		if(build == null){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILDING_NOT_EXIST));
			return;
		}
		if(build.getState() == State.BUILDING){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILDING_NOW));
			return;
		}
		if(build.getState() == State.CAPTURED){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_OCCUPIED_BY_OTHER));
			return;
		}
		int state = build.checkExpBookState();
		if(state == BuildV2.BOOK_STATE_CAN_PUT){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_NO_EXP_BOOK));
			return;
		}
		int errorType = build.canTakeExp();
		if(errorType == 1){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_NO_EXP_BOOK));
			return;
		}else if(errorType == 2){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_HAS_NO_EMPLOYEE));
			return;
		}else if(errorType == 3){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_TAKE_EXP_NOT_TIME_UP));
			return;
		}else if(errorType == 4){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_CANNOT_TAKE));
			return;
		}
		int[] results = build.takeExp();
		if(results[0] == 0){
			session.send(new HintResponse(req.getSerial(), MessageConst.BUILD_TAKE_NO_EXP));
			return;
		}
		session.send(new BuildTakeExpResponse(req.getSerial(), player, build, results));
	}
}



























